package com.xinggq.user.service.interceptor;

import com.alibaba.fastjson2.JSON;
import com.xinggq.common.CommonResult;
import com.xinggq.common.constant.AuthConstants;
import com.xinggq.common.enums.ResponseEnum;
import com.xinggq.user.service.entity.SysUserEntity;
import com.xinggq.user.service.service.UserInfoService;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

/**
 * 用户上下文拦截器
 * 处理请求头中的用户信息，确保UserContext能够正确获取用户信息
 *
 * @author xinggq
 * @since 2025/1/20
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class UserContextInterceptor implements HandlerInterceptor {

  private final UserInfoService userInfoService;

  @Override
  public boolean preHandle(@NonNull HttpServletRequest request,
      @NonNull HttpServletResponse response, @NonNull Object handler)
      throws IOException {
    try {
      // 检查是否有用户信息
      String userId = request.getHeader(AuthConstants.USER_ID_HEADER);
      String userName = request.getHeader(AuthConstants.USER_NAME_HEADER);
      String tenantId = request.getHeader(AuthConstants.TENANT_ID_HEADER);
      if (!StringUtils.hasText(userId) || !StringUtils.hasText(userName) || !StringUtils.hasText(
          tenantId)) {
        log.error("请求头中未找到用户ID，路径: {}", request.getRequestURI());
        buildAuthFail(response);
        return false;
      }
      // 验证请求头中的用户ID是否存在
      SysUserEntity userById = userInfoService.getUserById(Long.valueOf(userId));
      if (userById == null) {
        log.error("根据请求头中用户ID为查询到用户信息，路径: {}", request.getRequestURI());
        buildAuthFail(response);
        return false;
      }
      if (userById.getUsername().equals(userName) && userById.getTenantId()
          .equals(Long.valueOf(tenantId))) {
        return true;
      }
      log.error("请求头中用户ID与用户信息不一致，路径: {}", request.getRequestURI());
      // 继续处理请求
      buildAuthFail(response);
      return false;
    } catch (Exception e) {
      log.error("用户中心鉴权失败，路径: {}", request.getRequestURI(), e);
      buildAuthFail(response);
      return false;
    }

  }


  private void buildAuthFail(HttpServletResponse response) throws IOException {
    // 构建通用返回结果
    CommonResult<Object> result = CommonResult.fail(ResponseEnum.AUTH_FAILURE);

    // 设置响应
    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
    response.setCharacterEncoding(StandardCharsets.UTF_8.name());
    response.getWriter().write(JSON.toJSONString(result));
  }

  @Override
  public void afterCompletion(@NonNull HttpServletRequest request,
      @NonNull HttpServletResponse response,
      @NonNull Object handler, Exception ex) {
    // 请求完成后的清理工作（如果需要的话）
    if (log.isDebugEnabled()) {
      log.debug("请求处理完成: {}", request.getRequestURI());
    }
  }
}